#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>
#include <errno.h>
#include <libevdev-1.0/libevdev/libevdev.h>
#include <cstring>

// 转换 event type 到字符串
const char* event_type_to_string(unsigned int type) {
    switch (type) {
        case EV_SYN:    return "SYN";     // 同步事件
        case EV_KEY:    return "KEY";     // 按键事件
        case EV_ABS:    return "ABS";     // 绝对轴事件
        case EV_REL:    return "REL";     // 相对轴事件
        case EV_MSC:    return "MSC";     // 杂项事件
        case EV_SW:     return "SW";      // 开关事件
        case EV_LED:    return "LED";     // LED事件
        case EV_SND:    return "SND";     // 声音事件
        case EV_REP:    return "REP";     // 重复事件
        case EV_FF:     return "FF";      // 力反馈事件
        case EV_PWR:    return "PWR";     // 电源事件
        case EV_FF_STATUS: return "FF_STATUS"; // 力反馈状态
        default:        return "UNKNOWN";
    }
}

// 转换 EV_KEY 代码到字符串
const char* key_code_to_string(unsigned int code) {
    switch(code) {
        // 游戏手柄标准按键
        case BTN_SOUTH:     return "BTN_SOUTH(A)";
        case BTN_EAST:      return "BTN_EAST(B)";
        case BTN_NORTH:     return "BTN_NORTH(X)";
        case BTN_WEST:      return "BTN_WEST(Y)";
        case BTN_TL:        return "BTN_TL(LB)";
        case BTN_TR:        return "BTN_TR(RB)";
        case BTN_TL2:       return "BTN_TL2(LT)";
        case BTN_TR2:       return "BTN_TR2(RT)";
        case BTN_SELECT:    return "BTN_SELECT";
        case BTN_START:     return "BTN_START";
        case BTN_MODE:      return "BTN_MODE(HOME)";
        case BTN_THUMBL:    return "BTN_THUMBL(L3)";
        case BTN_THUMBR:    return "BTN_THUMBR(R3)";
        
        // 方向键（DPAD）
        case BTN_DPAD_UP:    return "BTN_DPAD_UP";
        case BTN_DPAD_DOWN:  return "BTN_DPAD_DOWN";
        case BTN_DPAD_LEFT:  return "BTN_DPAD_LEFT";
        case BTN_DPAD_RIGHT: return "BTN_DPAD_RIGHT";
        
        // 其他可能存在的按键
        case BTN_EXTRA:      return "BTN_EXTRA";
        case BTN_FORWARD:    return "BTN_FORWARD";
        case BTN_BACK:       return "BTN_BACK";
        default:            return "UNKNOWN_KEY";
    }
}

// 转换 EV_ABS 代码到字符串
const char* abs_code_to_string(unsigned int code) {
    switch(code) {
        // 摇杆和扳机轴
        case ABS_X:         return "ABS_X(LeftX)";
        case ABS_Y:         return "ABS_Y(LeftY)";
        case ABS_RX:        return "ABS_RX(RightX)";
        case ABS_RY:        return "ABS_RY(RightY)";
        case ABS_Z:         return "ABS_Z(LT)";
        case ABS_RZ:        return "ABS_RZ(RT)";
        
        // 方向键（HAT）
        case ABS_HAT0X:      return "ABS_HAT0X(DPadX)";
        case ABS_HAT0Y:      return "ABS_HAT0Y(DPadY)";
        
        // 其他可能存在的轴
        case ABS_THROTTLE:   return "ABS_THROTTLE";
        case ABS_RUDDER:     return "ABS_RUDDER";
        case ABS_WHEEL:      return "ABS_WHEEL";
        case ABS_GAS:        return "ABS_GAS";
        case ABS_BRAKE:      return "ABS_BRAKE";
        default:            return "UNKNOWN_AXIS";
    }
}

// 统一事件代码转换
const char* event_code_to_string(unsigned int type, unsigned int code) {
    if (type == EV_KEY) {
        return key_code_to_string(code);
    } else if (type == EV_ABS) {
        return abs_code_to_string(code);
    }
    return "UNKNOWN_CODE";
}

int main() {
    struct libevdev *dev = NULL;
    int fd;
    int rc;

    // 打开手柄设备文件（注意替换为你的设备路径）
    fd = open("/dev/input/event21", O_RDONLY | O_NONBLOCK);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 创建evdev设备对象
    rc = libevdev_new_from_fd(fd, &dev);
    if (rc < 0) {
        fprintf(stderr, "Failed to init libevdev: %s\n", strerror(-rc));
        exit(EXIT_FAILURE);
    }

    printf("Device name: %s\n", libevdev_get_name(dev));
    printf("Supported events:\n");
    
    // 打印设备支持的事件类型
    for (int i = 0; i <= EV_MAX; i++) {
        if (libevdev_has_event_type(dev, i)) {
            printf("  %s\n", event_type_to_string(i));
        }
    }

    // 读取事件
    while (1) {
        struct input_event ev;
        rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
        
        if (rc == 0) {
            // 过滤同步事件（EV_SYN）
            if (ev.type == EV_SYN) continue;
            
            const char *type_str = event_type_to_string(ev.type);
            const char *code_str = event_code_to_string(ev.type, ev.code);

            printf("[Event] Type:%-5s Code:%-15s Value:%d\n",
                   type_str, code_str, ev.value);
        } else if (rc == -EAGAIN) {
            // 没有更多事件，稍作等待
            usleep(10000);
        } else {
            perror("libevdev_next_event");
            break;
        }
    }

    // 清理资源
    libevdev_free(dev);
    close(fd);
    return 0;
}